#include "fault_info.hpp"
#include "BLE.hpp"
#include "crc16.hpp"
#include "indicator.hpp"
#include "CommProtocol.hpp"
#include "stdio.h"
extern BLE *ble;

void Send_DeviceFault_Info(uint8_t fault_type){
    char response_buffer[50];
    DeviceFaultResponseHeader_t *response_header = (DeviceFaultResponseHeader_t*)response_buffer;
    DeviceFaultResponseData_t *response_content = (DeviceFaultResponseData_t*)(response_buffer + sizeof(DeviceFaultResponseHeader_t));
    switch (fault_type)
    {

    case sd_mount_error:
        response_content->error_data = sd_mount_error;
        break;
    case flash_error:
        response_content->error_data = flash_error;
        break;   
    case verify_error:
        response_content->error_data = verify_error;
    default:
        response_content->error_data = input_type_error;
        break;
    }
    response_header->magic_number = 0xAABB;
    response_header->length = sizeof(DeviceFaultResponseData_t);
    response_header->reserved = 0xABCD;
    response_header->type = 0xEEEE;
    response_header->crc16 = crc16(response_content,sizeof(DeviceFaultResponseData_t));

    ble->write(response_buffer,sizeof(DeviceFaultResponseHeader_t) + sizeof(DeviceFaultResponseData_t) );
}

/*
主动发出错误信息
*/
char FaultInfo::set_error(char error_type_pram){
    switch (error_type_pram)
    {
    case none_error:
        this->error_type = none_error;
        break;
    case sd_mount_error:
        this->error_type = error_type_pram;
        break;
    case motor_init_positoin_error:
        this->error_type = error_type_pram;
        break;
    case motor_error:
        this->error_type = error_type_pram;
        break;
    default:
        this->error_type = none_error;
        break;
    }
    return 0;
}

char FaultInfo::get_error(){
    return this->error_type;
}

char FaultInfo::error_event(){
    Beeper *beeper = beeper->getInstance();
    switch (this->error_type)
    {
    case none_error:
        beeper->set(false);
        // this->error_type = none_error;
        break;
    case sd_mount_error:
        beeper->beeper_count(1);
        this->error_type = none_error;
        break;
    case motor_init_positoin_error:
        beeper->beeper_count(2);
        this->error_type = none_error;
        break;
    case motor_error:
        beeper->set(true);
        // this->error_type = motor_error;
        break;
    case flash_error:
        beeper->beeper_count(3);
        this->error_type = none_error;
        break;    
    default:
        // this->error_type = none_error;
        break;
    }
    return 0;
}

typedef struct ReturnErrorRespongseContent{
    int index;
    int error_type;
}ReturnErrorRespongseContent_t;

typedef struct OTAReturnErrorRespongseContent{
    char index;
    int error_type;
}__attribute__((packed)) OTAReturnErrorRespongseContent_t;

char FaultInfo::return_error(void *buffer,int error_type){
    char response_buffer[64];
    CommProtocolRequestHeader *header_return = (CommProtocolRequestHeader*)buffer;
    CommProtocolReadRequestContent_t *content_return = (CommProtocolReadRequestContent_t *)((uint8_t *)buffer + sizeof(CommProtocolRequestHeader));
    CommProtocolRequestHeader *response_header = (CommProtocolRequestHeader*)response_buffer;
    response_header->magic_number = header_return->magic_number;
    response_header->auth_code = 0xFFFF;
    response_header->type = header_return->type;
    response_header->length = header_return->length;
    response_header->crc16 = 0xFFFF;
    /* OTA的类型和其他类型不一致 这里是瑕疵 但是OTA已经跑通 暂时不做修改*/
    if( response_header->type == ResponseType_OTA ){
        OTAReturnErrorRespongseContent_t *response_content = (OTAReturnErrorRespongseContent_t*)((uint8_t *)response_buffer + sizeof(CommProtocolRequestHeader));
        response_content->index = content_return->index;
        response_content->error_type = error_type;
        ble->write(&response_buffer,sizeof(CommProtocolRequestHeader) + sizeof(OTAReturnErrorRespongseContent_t));
    }else{
        ReturnErrorRespongseContent_t *response_content = (ReturnErrorRespongseContent_t*)((uint8_t *)response_buffer + sizeof(CommProtocolRequestHeader));
        response_content->index = content_return->index;
        response_content->error_type = error_type;
        ble->write(&response_buffer,sizeof(CommProtocolRequestHeader) + sizeof(ReturnErrorRespongseContent_t));
    }
   
    return 0;
}